package com.system.web;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.common.redis.RedisUtil;
import org.apache.log4j.Logger;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.auth.domain.T_branch;
import com.auth.domain.T_function;
import com.auth.domain.T_role;
import com.auth.domain.T_role_function;
import com.auth.domain.T_user;
import com.auth.domain.T_user_function;
import com.auth.domain.T_user_role;
import com.auth.mapper.T_functionMapper;
import com.auth.mapper.T_roleMapper;
import com.auth.mapper.T_role_functionMapper;
import com.auth.mapper.T_userMapper;
import com.auth.mapper.T_user_functionMapper;
import com.auth.mapper.T_user_roleMapper;
import com.auth.service.T_branchService;
import com.auth.service.T_roleService;
import com.auth.web.spring.AuthUtils;
import com.common.servlet.AttributeListener;
import com.common.utils.DateUtil;
import com.common.utils.SystemConstants;
import com.common.utils.SystemDataDicCache;
import com.system.domain.T_data_dic;
import com.system.domain.T_login_log;
import com.system.mapper.T_data_dicMapper;
import com.system.mapper.T_login_logMapper;
import com.system.service.LogonService;

/**
 * 登录页面
 *
 * @author davexin
 */
@Controller
public class LoginController {

    private static Logger log = Logger.getLogger(LoginController.class.getName());

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private LogonService logonService;
    @Resource
    private T_branchService t_branchService;
    @Resource
    private T_roleService t_roleService;

    //@Transactional(rollbackFor={Exception.class, RuntimeException.class})
    @RequestMapping(value = "/htlogout")
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        //设置登出日志信息
        T_login_log loginlog = new T_login_log();

        try {
            loginlog.setLogin_addr(getIp(request));
            loginlog.setLogin_out_tm(DateUtil.getCurrDateTime());
            loginlog.setUserid("" + request.getSession().getAttribute("FREE_CURRENT_USER"));
            loginlog.setLogin_remark("成功退出");
            loginlog.setSession_id(request.getSession().getId());
            logonService.saveLoginlog(loginlog);

            //			T_login_log loginlog2 = new T_login_log();
            //			String errstr = "12345678901234567890"; //数据库最长是14位，设置一个超过14位的字符，促使其报错；
            //			loginlog2.setLogin_in_tm(errstr);
            //			logonService.saveLoginlog(loginlog, loginlog2); //此时应该2个save都报错，事务都回滚，插入2条数数据都失败，如果插入一条成功，则是事务不一致，需要重新检查事务配置问题；

            request.getSession().removeAttribute("FREE_CURRENT_USER");
            request.getSession().removeAttribute("FREE_CURRENT_USER_OBJ");
            request.getSession().removeAttribute("FREE_BRANCHID");
            request.getSession().removeAttribute("FREE_USER_AUTH");
            //request.getSession().invalidate(); //如果调用，需要把ie窗口关闭，否则会报错；
            AttributeListener.remove(loginlog.getUserid());

            log.debug("------退出时清除用户session------");
        } catch (Exception e) {
            log.error(e);
            //此处必须抛出运行时异常，否则事务不会回滚，造成一个事务成功，一个事务失败；
            //throw new RuntimeException();
        }

        return "login/htlogin";
    }

    /**
     * 前台退出登录
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/qtLogout")
    public String qtLogout(HttpServletRequest request, HttpServletResponse response) {
        String tempBathPath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "" + request.getContextPath() + "/";
        //设置登出日志信息
        T_login_log loginlog = new T_login_log();

        try {
            loginlog.setLogin_addr(getIp(request));
            loginlog.setLogin_out_tm(DateUtil.getCurrDateTime());
            loginlog.setUserid("" + request.getSession().getAttribute("FREE_CURRENT_USER"));
            loginlog.setLogin_remark("成功退出");
            loginlog.setSession_id(request.getSession().getId());
            logonService.saveLoginlog(loginlog);

            //			T_login_log loginlog2 = new T_login_log();
            //			String errstr = "12345678901234567890"; //数据库最长是14位，设置一个超过14位的字符，促使其报错；
            //			loginlog2.setLogin_in_tm(errstr);
            //			logonService.saveLoginlog(loginlog, loginlog2); //此时应该2个save都报错，事务都回滚，插入2条数数据都失败，如果插入一条成功，则是事务不一致，需要重新检查事务配置问题；

            request.getSession().removeAttribute("FREE_CURRENT_USER");
            request.getSession().removeAttribute("FREE_CURRENT_USER_OBJ");
            request.getSession().removeAttribute("FREE_BRANCHID");
            request.getSession().removeAttribute("FREE_USER_AUTH");
            //request.getSession().invalidate(); //如果调用，需要把ie窗口关闭，否则会报错；
            AttributeListener.remove(loginlog.getUserid());

            log.debug("------退出时清除用户session------");
        } catch (Exception e) {
            log.error(e);
            //此处必须抛出运行时异常，否则事务不会回滚，造成一个事务成功，一个事务失败；
            //throw new RuntimeException();
        }

        return "redirect:" + tempBathPath;
    }

    @RequestMapping(value = "/htlogin")
    public String htlogin(HttpServletRequest request, HttpServletResponse response) {
        log.debug("------跳转到后台登录页面login/htlogin.jsp------");
        return "login/htlogin";
    }

    @RequestMapping(value = "/changePassword")
    public String changePassword(HttpServletRequest request, HttpServletResponse response) {
        log.debug("------跳转到修改密码页面------");
        return "login/changePassword";
    }

    @RequestMapping(value = "/showUserDetail")
    public String showUserDetail(HttpServletRequest request, HttpServletResponse response) {
        log.debug("------跳转到用户信息页面------");
        return "login/showUserDetail";
    }


    /**
     * 后台登录
     *
     * @param request
     * @param response
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "/htlogon")
    public String htlogon(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
        String tempBathPath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "" + request.getContextPath() + "/";
        //Rm dao = new Rm();
        String userid = request.getParameter("userid");
        String password = request.getParameter("password");
        //设置登录日志信息
        T_login_log loginlog = new T_login_log();
        String logmes = "登录失败";

        try {
            loginlog.setLogin_addr(getIp(request));
            loginlog.setLogin_in_tm(DateUtil.getCurrDateTime());
            //loginlog.setLogin_out_tm("");
            loginlog.setUserid(userid);
            loginlog.setSession_id(request.getSession().getId());

            //0、------判断系统是否熔断start-------------------------------------------------------------//
//			String rd_flag = "";
//			Object obj = SystemDataDicCache.findByDataNo(SystemConstants.SYSTEM_LOGIN_FLAG);
//			if(obj!=null){
//				T_data_dic datadic = (T_data_dic)obj;
//				rd_flag = datadic.getData_name();
//			}else{
//				//如果缓存中不存在，则去数据库加载后，并且更新缓存
//				T_data_dic datadictemp = new T_data_dic();
//				datadictemp.setData_no(SystemConstants.SYSTEM_LOGIN_FLAG);
//				datadictemp = (T_data_dic)logonService.findByDataNo(datadictemp).get(0);
//				SystemDataDicCache.setRdFlag(datadictemp);
//				rd_flag = datadictemp.getData_name();
//				log.debug("------加载熔断机制数据------");
//			}

            //if(rd_flag!=null&&rd_flag.equals("true")){ //熔断:true; 正常：false;
            if (false) {
                if (SystemConstants.SYSTEM_RD_MANAGER.equals(userid)) {
                    log.error("------熔断后系统处理，熔断管理员登录------");
                } else {
                    log.error("------系统已经熔断，禁止登录、交易------");
                    redirectAttributes.addAttribute("loginMess", "系统熔断，禁止登录!");
                    return "redirect:" + tempBathPath + "htlogin";
                }
            }
            //0、------判断熔断结束 end------------------------------------------------------------------//

            T_user user = new T_user();
            if (userid != null && !userid.equals("")) {
                user.setUserid(userid);
                log.debug("------userid=" + userid);
            }
            if (password != null && !password.equals("")) {
                //log.debug("------password="+password);
            }
            //T_user_detail  sys_user = (T_user_detail)dao.t_user_detailFindByUsername(user);
            T_user sys_user = null;
            //user.setPageSize(10);
            user.setStartNo(0);
            user.setEndNo(10);
            List userList = logonService.findAllUser(user); //mapper.findAll(user);
            if (userList != null && userList.size() == 1) {
                sys_user = (T_user) userList.get(0);
                sys_user.setMemo2(loginlog.getLogin_addr());
                sys_user.setMemo3(loginlog.getLogin_in_tm());
                log.debug("------后台密码与前端密码匹配？=" + sys_user.getPassword().equals(password));
                if (sys_user.getPassword().equals(password)) {
                    if (sys_user.getStatus().equals("1")) { //状态：1：正常；0：无效；2：冻结；
                        //验证合法，跳转到首页
                        log.error("------登录用户密码正确------");
						/*
						//1、-------------------------剔除同一账号已经登录的session  开始------------------------------------------------------//
						if ( null != AttributeListener.getOnlineSession().get(userid) ) {
							//第一次登录的用户session销毁
							//将第一次登录用户的信息从map中移除
							log.debug("---系统中存在已经登录的同一账号=（"+userid+"），需要把前面登录的账号剔除------");
							//当前session失效时，下面一行代码会报：java.lang.IllegalStateException: getAttributeNames: Session already invalidated
							HttpSession hs = (HttpSession) AttributeListener.getOnlineSession().get(userid);
							AttributeListener.getOnlineSession().remove(userid);
							Enumeration e = hs.getAttributeNames();
							while (e.hasMoreElements()) {
								String sessionName = (String) e.nextElement();
								// 清空session
								hs.removeAttribute(sessionName);
								log.error("------清除"+userid+"已经登录的session="+sessionName);
							}
							// hs.invalidate();
						}
						*/

                        request.getSession().setAttribute(SystemConstants.SESSIONNAME_OBJECT, sys_user);
                        request.getSession().setAttribute("FREE_BRANCHID", sys_user.getBranchid());
                        //设置sesion中 角色信息,map对象，key存储了functid，value为空；
                        request.getSession().setAttribute("FREE_USER_AUTH", getUserPower(userid));
                        //设置是否是管理员；
                        request.getSession().setAttribute("FREE_USER_ISMANAGER", sys_user.getIsmanager());
                        //设置session中用户名称
                        request.getSession().setAttribute(SystemConstants.SESSIONNAME, userid);

                        //modify by Davexin，防止ie8 redirect后sessionid是新的，导致left.jsp取不到当前session对应菜单信息；
                        //并且在left.jsp中调用的controller中需要使用  HttpSession session=request.getSession(false);
                        HttpSession session = request.getSession(true);
                        session.setAttribute(SystemConstants.SESSIONNAME_OBJECT, sys_user);
                        session.setAttribute("id", sys_user.getId());
                        session.setAttribute("username", sys_user.getUsername());
                        session.setAttribute("userid", sys_user.getUserid());
                        session.setAttribute("FREE_BRANCHID", sys_user.getBranchid());
                        request.getSession().setAttribute("FREE_BRANCH_NAME", sys_user.getBranchid());
                        log.error("******************************sys_user.getBranchid()=" + sys_user.getBranchid());

                        //redis 使用 start ;x需要启动redis服务，否则调用登录时报错，不能登录；
                        //redisUtil.set("user."+sys_user.getUsername(), sys_user);
                        //redisUtil.set("user."+sys_user.getUserid(), sys_user);
                        //log.info(">>>>>>redis getbyUsername="+redisUtil.get("user."+sys_user.getUsername()));
                        //log.info(">>>>>>redis getUserid="+redisUtil.get("user."+sys_user.getUserid()));
                        //redis 使用 end

                        //设置机构部门信息
                        //T_branch b = new T_branch();
                        //b.setId(new Integer(sys_user.getBranchid()));
                        //T_branch nb = (T_branch) t_branchService.findById(b);
                        //log.error("******************************nb.getBranchid()=" + nb.getName() + ";" + nb.getBranchid());
                        //request.getSession().setAttribute("FREE_BRANCH_NAME", nb.getName());

                        //设置角色信息
/*						T_role r = new T_role();
						r.(sys_user.getBranchid());
					    b = (T_branch)t_branchService.findById(b);
						request.getSession().setAttribute("FREE_ROLE_NAME", r.getName());*/

                        //设置sesion中 角色信息,map对象，key存储了functid，value为空；
                        Map userPower = getUserPower(userid);
                        List userFunctionList = getPower(userPower, userid);
                        session.setAttribute("FREE_USER_AUTH", userFunctionList);
                        //设置是否是管理员；
                        session.setAttribute("FREE_USER_ISMANAGER", sys_user.getIsmanager());
                        //设置session中用户名称
                        session.setAttribute(SystemConstants.SESSIONNAME, userid);
                        /**
                         * 1、本次登录用户添加到map中,下面这行必须跟在设置userid session后面，否则，request.getSession的值是紧跟着的上一行代码的session；
                         * 2、并且在put之后不能再设置session，否则会以最后一个session设置的key为准，覆盖前面的；
                         */
                        AttributeListener.getOnlineSession().put(userid, request.getSession());

                        //1、--------------------------剔除同一账号已经登录的session  结束------------------------------------------------------//

                        //设置登录失败日志
                        logmes = "登录成功";
                        log.error(" 当前登录 session id=" + request.getSession().getId());
                        //return "redirect:"+tempBathPath+"main/sy"; //老的首页，后面该为新的bootstrap风各后台首页；
                        //return "redirect:"+tempBathPath+"toIndex"; //老的后台首页
                        return "redirect:" + tempBathPath + "toIndex1"; //洗的后台门户页；
                    } else {
                        logmes = "账号状态无效，无法登录！";
                        redirectAttributes.addAttribute("loginMess", logmes);
                        return "redirect:" + tempBathPath + "htlogin";
                    } //end状态不对；
                } else { //密码不对；
                    //设置登录失败日志
                    logmes = "登录失败,密码不正确!";
                    redirectAttributes.addAttribute("loginMess", logmes);
                    return "redirect:" + tempBathPath + "htlogin";
                }
            } else if (userList != null && userList.size() > 1) {
                //设置登录失败日志
                logmes = "登录失败,同时存在账号多个，无法定位是哪个账号，请与管理员联系!";
                redirectAttributes.addAttribute("loginMess", logmes);
                return "redirect:" + tempBathPath + "htlogin";
            } else {
                log.debug("------账号不存在，请于管理员联系------");
                //设置登录失败日志
                logmes = "登录失败,账号不存在!";
                redirectAttributes.addAttribute("loginMess", logmes);
                return "redirect:" + tempBathPath + "htlogin";
            }
        } catch (Exception e) {
            log.error(e);
            e.printStackTrace();
            logmes = "登录失败,遇到异常！请查看日志或者与管理员联系！";
            log.error("系统出错，请联系管理员 ！");
        } finally {
            loginlog.setLogin_remark(logmes);
            logonService.saveLoginlog(loginlog);
        }
        //return "/main/index";  //老的首页；
        return ""; //新的首页；
    }

    /*
     * 前台登录
     */
    @RequestMapping(value = "/qtlogon")
    public String qtlogon(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
        String tempBathPath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "" + request.getContextPath() + "/";
        //Rm dao = new Rm();
        String userid = request.getParameter("userid");
        String password = request.getParameter("password");
        //设置登录日志信息
        T_login_log loginlog = new T_login_log();
        String logmes = "登录失败";

        try {
            loginlog.setLogin_addr(getIp(request));
            loginlog.setLogin_in_tm(DateUtil.getCurrDateTime());
            //loginlog.setLogin_out_tm("");
            loginlog.setUserid(userid);
            loginlog.setSession_id(request.getSession().getId());

            //0、------判断系统是否熔断start-------------------------------------------------------------//
			/*
			String rd_flag = "";
			Object obj = SystemDataDicCache.findByDataNo(SystemConstants.SYSTEM_LOGIN_FLAG);
			if(obj!=null){
				T_data_dic datadic = (T_data_dic)obj;
				rd_flag = datadic.getData_name();
			}else{
				//如果缓存中不存在，则去数据库加载后，并且更新缓存
				T_data_dic datadictemp = new T_data_dic();
				datadictemp.setData_no(SystemConstants.SYSTEM_LOGIN_FLAG);
				datadictemp = (T_data_dic)logonService.findByDataNo(datadictemp).get(0);
				SystemDataDicCache.setRdFlag(datadictemp);
				rd_flag = datadictemp.getData_name();
				log.debug("------加载熔断机制数据------");
			}

			if(rd_flag!=null&&rd_flag.equals("true")){ //熔断:true; 正常：false;
				if(SystemConstants.SYSTEM_RD_MANAGER.equals(userid)){
					log.error("------熔断后系统处理，熔断管理员登录------");
				}else{
					log.error("------系统已经熔断，禁止登录、交易------");
					redirectAttributes.addAttribute("loginMess", "系统熔断，禁止登录!");
					return "redirect:"+tempBathPath+"denglu.jsp";
				}
			}
			*/
            //0、------判断熔断结束 end------------------------------------------------------------------//

            T_user user = new T_user();
            if (userid != null && !userid.equals("")) {
                user.setUserid(userid);
                log.debug("------userid=" + userid);
            }
            if (password != null && !password.equals("")) {
                //log.debug("------password="+password);
            }
            //T_user_detail  sys_user = (T_user_detail)dao.t_user_detailFindByUsername(user);
            T_user sys_user = null;
            //user.setPageSize(10);
            user.setStartNo(0);
            user.setEndNo(10);
            List userList = logonService.findAllUser(user); //mapper.findAll(user);
            if (userList != null && userList.size() == 1) {
                sys_user = (T_user) userList.get(0);
                sys_user.setMemo2(loginlog.getLogin_addr());
                sys_user.setMemo3(loginlog.getLogin_in_tm());
                log.debug("------后台密码与前端密码匹配？=" + sys_user.getPassword().equals(password));
                if (sys_user.getPassword().equals(password)) {
                    if (sys_user.getStatus().equals("1")) { //状态：1：正常；0：无效；2：冻结；
                        //验证合法，跳转到首页
                        log.error("------登录用户密码正确------");

                        //1、-------------------------剔除同一账号已经登录的session  开始------------------------------------------------------//
                        if (null != AttributeListener.getOnlineSession().get(userid)) {
                            //第一次登录的用户session销毁
                            //将第一次登录用户的信息从map中移除
                            log.debug("---系统中存在已经登录的同一账号=（" + userid + "），需要把前面登录的账号剔除------");
                            HttpSession hs = (HttpSession) AttributeListener.getOnlineSession().get(userid);
                            AttributeListener.getOnlineSession().remove(userid);
                            Enumeration e = hs.getAttributeNames();
                            while (e.hasMoreElements()) {
                                String sessionName = (String) e.nextElement();
                                // 清空session
                                hs.removeAttribute(sessionName);
                                log.error("------清除" + userid + "已经登录的session=" + sessionName);
                            }
                            // hs.invalidate();
                        }
                        request.getSession().setAttribute(SystemConstants.SESSIONNAME_OBJECT, sys_user);
                        request.getSession().setAttribute("FREE_BRANCHID", sys_user.getBranchid());

                        //设置sesion中 角色信息,map对象，key存储了functid，value为空；
                        request.getSession().setAttribute("FREE_USER_AUTH", getUserPower(userid));
                        //设置是否是管理员；
                        request.getSession().setAttribute("FREE_USER_ISMANAGER", sys_user.getIsmanager());
                        //设置session中用户名称
                        request.getSession().setAttribute(SystemConstants.SESSIONNAME, userid);
                        /**
                         * 1、本次登录用户添加到map中,下面这行必须跟在设置userid session后面，否则，request.getSession的值是紧跟着的上一行代码的session；
                         * 2、并且在put之后不能再设置session，否则会以最后一个session设置的key为准，覆盖前面的；
                         */
                        AttributeListener.getOnlineSession().put(userid, request.getSession());

                        //1、--------------------------剔除同一账号已经登录的session  结束------------------------------------------------------//

                        //设置登录失败日志
                        logmes = "登录成功!";
                        redirectAttributes.addAttribute("loginMess", logmes);
                        return "redirect:" + tempBathPath + "denglu.jsp";
                    } else {
                        logmes = "账号状态无效，无法登录！";
                        redirectAttributes.addAttribute("loginMess", logmes);
                        request.getSession().setAttribute("loginMess", logmes);
                        return "redirect:" + tempBathPath + "denglu.jsp";
                    } //end状态不对；
                } else { //密码不对；
                    //设置登录失败日志
                    logmes = "登录失败,密码不正确!";
                    redirectAttributes.addAttribute("loginMess", logmes);
                    request.getSession().setAttribute("loginMess", logmes);
                    return "redirect:" + tempBathPath + "denglu.jsp";
                }
            } else if (userList != null && userList.size() > 1) {
                //设置登录失败日志
                logmes = "登录失败,同时存在账号多个，无法定位是哪个账号，请与管理员联系!";
                redirectAttributes.addAttribute("loginMess", logmes);
                request.getSession().setAttribute("loginMess", logmes);
                return "redirect:" + tempBathPath + "denglu.jsp";
            } else {
                log.debug("------账号不存在，请于管理员联系------");
                //设置登录失败日志
                logmes = "登录失败,账号不存在!";
                redirectAttributes.addAttribute("loginMess", logmes);
                request.getSession().setAttribute("loginMess", logmes);
                return "redirect:" + tempBathPath + "denglu.jsp";
            }
        } catch (Exception e) {
            log.error(e);
            e.printStackTrace();
            logmes = "登录失败,遇到异常！请查看日志或者与管理员联系！";
            log.error("系统出错，请联系管理员 ！");
            request.getSession().setAttribute("loginMess", logmes);
            redirectAttributes.addAttribute("loginMess", logmes);
        } finally {
            loginlog.setLogin_remark(logmes);
            logonService.saveLoginlog(loginlog);
        }
        //return "/";
        return "redirect:" + tempBathPath + "denglu.jsp";
    }

    /**
     * 如果登录成功，取得登录人的权限菜单信息,存储在map中，key只存储functid，value为空；非
     *
     * @param userid
     * @return map
     */
    private Map getUserPower(String userid) {
        Map map = new HashMap();
        Map functionMap = new HashMap();
        List functionList = null;
        T_user_function uf = new T_user_function();
        uf.setStartNo(0);
        uf.setEndNo(10000);
        uf.setUserid(userid);

        //用户角色条件设置
        T_user_role ur = new T_user_role();
        ur.setStartNo(0);
        ur.setEndNo(10000);
        ur.setUserid(userid);

        T_role_function rf = new T_role_function();
        rf.setStartNo(0);
        rf.setEndNo(10000);
        T_role_function rftemp = null;

        T_function function = new T_function();
        function.setStartNo(0);
        function.setEndNo(10000);

        int functid = -1;
        List userFunctList = new ArrayList();
        List rflist = new ArrayList();
        try {

            //1、首先查询出全部function数据，存放到functMap中,共后面比对后放到输出的map中；
            T_function ta = new T_function();
            ta.setFunctid(0); //从根目录开始查询；
            ta.setStartNo(0);
            ta.setEndNo(10000);
            ta.setStatus("1"); //有效,此处设置无用，查询条件中没有该条件；

            //查询所有有效菜单信息
            functionList = logonService.findAllFunction(ta); //functionMapper.findAll(ta);
            Iterator tempfl = functionList.iterator();
            while (tempfl.hasNext()) {
                ta = null;
                ta = (T_function) tempfl.next();
                if (ta.getStatus().equals("1")) { //无效的菜单不显示；只显示有效的菜单；
                    functionMap.put(ta.getFunctid(), ta);
                    log.debug("------1、1系统有效菜单functid=" + ta.getFunctid() + "；functname=" + ta.getFunctname());
                } else {
                    log.debug("------1、2系统》》》》......无效......《《《菜单functid=" + ta.getFunctid() + "；functname=" + ta.getFunctname());
                }
            }

            //2、取出全部的有效的role信息，后面过滤数据使用
            Map roleMap = new HashMap();
            T_role tr = new T_role();
            tr.setStatus("1"); //只查询有效状态的role信息;
            tr.setStartNo(0);
            tr.setEndNo(10000);
            List rolelist = logonService.findAllRole(tr);
            Iterator ittr = rolelist.iterator();
            while (ittr.hasNext()) {
                tr = (T_role) ittr.next();
                roleMap.put(tr.getId(), ""); //以roleid为key存放到map中，value为空；
                log.debug("------2、系统有效角色有：" + tr.getRolename() + ";roleid=" + tr.getId());
            }

            //3、查询用户对应角色，然后查询角色对应功能菜单；
            List userRoleList = logonService.findAllUserRole(ur); //userRoleMapper.findAll(ur);
            if (userRoleList != null && userRoleList.size() > 0) {
                Iterator it = userRoleList.iterator();
                Iterator itrf = null;
                while (it.hasNext()) {
                    ur = (T_user_role) it.next();
                    int roleid = ur.getRoleid();
                    rf.setRoleid(roleid);
                    log.debug("------3、1操作员" + userid + "具有的角色有：" + roleid);
                    //加一层过滤，如果roleid对应role的status为无效状态，不能显示该权限，或者不能使用该权限；
                    if (roleMap.containsKey(roleid)) {
                        log.debug("------3、2操作员" + userid + "具有的......有效......角色有：" + roleid);
                        //查询角色对应功能菜单；roleid对应的functid；
                        rflist = logonService.findAllRoleFunction(rf); //roleFunctionMapper.findAll(rf);
                        if (rflist != null && rflist.size() > 0) {
                            itrf = rflist.iterator();
                            while (itrf.hasNext()) {
                                rftemp = null;
                                rftemp = (T_role_function) itrf.next();
                                functid = rftemp.getFunctid();
                                if (!map.containsKey(functid)) {
                                    if (functionMap.get(functid) != null) { //防止脏数据，有些菜单删除后，在权限表中没有删除干净，造成为null；权限有而菜单function数据已经无（已删除）；
                                        //map.put(functid, functionMap.get(functid)); //如果map中还不存在该functid，则加入，否则不重复加入；
                                        map.put(functid, "");
                                        log.debug("------3.3操作员" + userid + ":查询到role对应权限function到map中，functid=" + functid);
                                    } else {
                                        log.debug("------3.4操作员" + userid + ":对应role查询到对应权限functid=" + functid + "为脏数据或者无效菜单，无需加入！");
                                    }
                                }
                            }
                        }
                    } //end role有效状态过滤；
                }
            }

            //4、查询用户直接分配的对应功能；
            userFunctList = logonService.findAllUserFunction(uf); //userFunctionMapper.findAll(uf);
            if (userFunctList != null && userFunctList.size() > 0) {
                Iterator ituf = userFunctList.iterator();
                while (ituf.hasNext()) {
                    uf = (T_user_function) ituf.next();
                    if (!map.containsKey(uf.getFunctid())) {
                        //此处考虑替换为在该方法中只查询一次，查询出全部function表数据，然后从内容中去查询比对；
                        functid = uf.getFunctid();
                        if (functionMap.get(functid) != null) { //防止脏数据，有些菜单删除后，在权限表中没有删除干净，造成为null；权限有而菜单function数据已经无（已删除）；
                            //map.put(functid, functionMap.get(functid)); //如果map中还不存在该functid，则加入，否则不重复加入；
                            map.put(functid, "");
                            log.debug("------4.1操作员" + userid + ":查询到对应权限function到map中，functid=" + uf.getFunctid());
                        } else {
                            log.debug("------4.2操作员" + userid + ":查询到对应权限functid=" + uf.getFunctid() + "为脏数据或者无效菜单，无需加入！");
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error(e);
            e.printStackTrace();
            log.error("系统出错，请联系管理员 ！");
        }

        return map;
    }

    /*
     * 根据session中存储的authMap(乱序的function)，根据userid加工正常顺序的function列表；
     */
    public List getPower(Map authMap, String userid) {
        List retList = new ArrayList();

        List functionList = null;
        T_user_function uf = new T_user_function();
        uf.setStartNo(0);
        uf.setEndNo(10000);

        T_user_role ur = new T_user_role();
        ur.setStartNo(0);
        ur.setEndNo(10000);

        T_role_function rf = new T_role_function();
        rf.setStartNo(0);
        rf.setEndNo(10000);

        T_function function = new T_function();
        function.setStartNo(0);
        function.setEndNo(10000);

        //Map authMap = (Map)request.getSession().getAttribute("FREE_USER_AUTH");
        //modify by davexin @20161126, 防止ie8 redirector后，取不到session的 问题；
        //session中保存的functid对应map信息；
        //HttpSession session=request.getSession(false);
        //Map authMap = (Map)session.getAttribute("FREE_USER_AUTH");

        Map functionMap = new HashMap();
        int functid = -1;
        List userFunctList = new ArrayList();
        List rflist = new ArrayList();
        try {
            //String tempBathPath= request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort() +""+ request.getContextPath()+"/";
            //String userid = (String) request.getSession().getAttribute("FREE_CURRENT_USER");
            uf.setUserid(userid);

            //1、首先查询出全部function数据，存放到functionMap中;数据是按照 functlevel、showseq 升序排列；
            T_function ta = new T_function();
            ta.setFunctid(0); //从根目录开始查询；
            ta.setStartNo(0);
            ta.setEndNo(10000);
            ta.setStatus("1"); //有效状态，此处设置无效，因为查询条件中没有该条件，只支持functid查询条件；需要在登录时的数据中过滤无效菜单；
            functionList = logonService.findAllFunction(ta);
            Iterator tempfl = functionList.iterator();
            while (tempfl.hasNext()) {
                ta = null;
                ta = (T_function) tempfl.next();
                functionMap.put(ta.getFunctid(), ta);
                //log.debug("------系统有效菜单functid="+ta.getFunctid()+"；functname="+ta.getFunctname());
            }

            //2、按照树形菜单顺序，根据权限map中的数据，删除没有权限的功能菜单，返回所有不重复的所有t_function数据；并且排列成一个树形菜单顺序输出，页面上只需要顺序输出就可以；
            List sortlist = AuthUtils.sortFunctionList(functionList);
            T_function mf = null;
            Iterator itmenu = sortlist.iterator();
            while (itmenu.hasNext()) {
                mf = (T_function) itmenu.next();
                //log.error("<<<<<<<<authMap="+authMap+">>>>>>>>>>>>>>mf.getFunctid()="+ mf.getFunctid());
                //log.error("<<<<<<<<session id2="+request.getSession().getId());
                //如果权限中存在，则
                if (authMap.containsKey(mf.getFunctid())) {
                    //sortlist.remove(mf);//此方法会报错；
                    retList.add(mf);
                    //log.debug("------最终计算出权限数据为：functid="+mf.getFunctid()+";functlevel="+mf.getFunctlevel()+";functname="+mf.getFunctname());
                }
            }
        } catch (Exception e) {
            log.error(e);
            e.printStackTrace();
            log.error("系统出错，请联系管理员 ！");
        }
        return retList;
    }

    /**
     * 获取访问者ip
     *
     * @param request
     * @return
     */
    public String getIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
